<?php

namespace app\admin\logic\material;

use app\admin\logic\system\Log;
use app\admin\model\material\Material as MaterialModel;
use app\common\event\subscribes\attach\Attach as AttachSubscribes;
use app\common\exception\LogicException;
use app\common\helper\util\Tool;
use app\common\logic\Attach;
use Exception;
use think\db\exception\DbException;
use think\facade\Event;
use think\facade\Request;
use think\Paginator;

class Material extends MaterialModel
{
    /**
     * 获取列表
     * Author   Martinsun<syh@sunyonghong.com>
     * Date 2020-04-21
     *
     * @param string $type [description]
     * @param array  $map
     * @param int    $delete
     * @return Paginator [type]                               [description]
     * @throws DbException
     */
    public function getList(string $type, array $map = [], $delete = 0): Paginator
    {
        if ($delete) {
            $builder = $this->onlyTrashed()->scope('materialType', $type);
        } else {
            $builder = $this->scope('materialType', $type);
        }

        $map['category'] && $builder->where('material_category_id', $map['category']);

        if ($map['filename']) {
            // 查询符合文件名的素材
            $builder = $builder->withJoin(['attach'])->where('attach.filename', 'like', '%' . $map['filename'] . '%');

        } else {
            $builder = $builder->with(['attach']);
        }

        return $builder->order([
            '__TABLE__.update_time' => 'DESC',
            '__TABLE__.id'          => 'DESC'
        ])->hidden(['attach'])->paginate($this->getListRows());
    }

    /**
     * 删除素材-- 假删除
     * Author   Martinsun<syh@sunyonghong.com>
     * Date 2020-04-23
     *
     * @param    [type]                         $id [description]
     */
    public function deleteMaterial($id)
    {
        $ids = is_array($id) ? $id : array_unique(array_filter(explode(',', $id)));
        $this->whereIn('id', $ids)->selectOrFail()->each(function ($item) {
            if (!$item->delete()) {
                throw new LogicException('删除失败');
            }
            app(Category::class)->where('id', $item->getAttr('material_category_id'))->dec('num')->update();
            $title = $item->attach->filename;
            Log::write('删除并移入回收站【' . $title . '】', 'material', 'delete', true);
        });
    }

    /**
     * 删除素材-- 真删除
     * Author   Martinsun<syh@sunyonghong.com>
     * Date 2020-04-23
     *
     * @param    [type]                         $id [description]
     */
    public function deleteMaterialReally($id)
    {
        $ids = is_array($id) ? $id : array_unique(array_filter(explode(',', $id)));
        $this->onlyTrashed()->whereIn('id', $ids)->selectOrFail()->each(function ($item) {
            if (!$item->force()->delete()) {
                throw new LogicException('删除失败');
            }
            // Category::where('id', $item->getAttr('material_category_id'))->dec('num')->update();
            $title = $item->attach->filename;
            // 删除附件
            Event::subscribe(AttachSubscribes::class);
            Event::trigger('AttachTrueDeleted', $item->attach_id);
            Log::write('彻底删除素材【' . $title . '】', 'material', 'delete', true);
        });

    }

    /**
     * 移动素材分组
     * Author   Martinsun<syh@sunyonghong.com>
     * Date 2020-04-23
     *
     * @param    [type]                         $ids      [description]
     * @param    [type]                         $category [description]
     */
    public function moveMaterial($ids, $category)
    {
        $ids         = is_string($ids) ? explode(',', $ids) : $ids;
        $oldCategory = 0;
        $is_del      = 0;
        // 当前分组
        if (!empty($ids)) {
            $id          = $ids[0];
            $oldCategory = $this->withTrashed()->where('id', $id)->value('material_category_id');
            $is_del      = $this->withTrashed()->where('id', $id)->value('delete_time') ? 1 : 0;
        }
        $res = $this->withTrashed()->whereIn('id', $ids)->save(['delete_time' => null, 'material_category_id' => $category]);
        if (!$res) {
            throw new LogicException('移动分组失败');
        }

        $count = count($ids);
        app(Category::class)->where('id', $category)->inc('num', $count)->update();
        if ($oldCategory && $is_del == 0) {
            app(Category::class)->where('id', $oldCategory)->dec('num', $count)->update();
        }

        try {
            foreach ($ids as $id) {
                $material = $this->where('id', $id)->findOrEmpty();
                $title    = $material->attach->filename;
                Log::write('移动素材【' . $title . '】', 'material', 'update', true);
            }
        } catch (Exception $e) {
        }
    }

    /**
     * 素材上传
     * Author   Martinsun<syh@sunyonghong.com>
     * Date 2020-04-24
     *
     * @param array  $attach_ids
     * @param string $type
     * @param        $category
     * @return int [type]                         [description]
     */
    public function addMaterial(array $attach_ids, string $type, $category): int
    {
        if (count($attach_ids) == 0) {
            throw new LogicException('请选择要上传的素材');
        }
        $check = [
            'material_type' => $this->materialTypes[$type] ?? 0,
        ];
        // 验证数据
        $this->getValidate()->scene('create')->failException()->check($check);

        $datas         = [];
        $admin_user_id = request()->admin_user_id;
        foreach ($attach_ids as $attach_id) {
            $data    = [
                'material_type'        => $this->materialTypes[$type],
                'attach_id'            => $attach_id,
                'material_category_id' => $category,
                'mhm_id'               => request()->mhm_id,
                'admin_user_id'        => $admin_user_id,
                'update_time'          => Request::time(),
            ];
            $datas[] = $data;
        }

        $count = $this->limit(50)->insertAll($datas);

        if ($count == 0) {
            throw new LogicException('上传素材失败');
        }

        app(Category::class)->where('id', $category)->inc('num', $count)->update();

        try {
            foreach ($attach_ids as $attach_id) {
                $title = app(Attach::class)->getAttachTitle($attach_id);
                Log::write('上传素材【' . $title . '】', 'material', 'create', true);
            }
        } catch (Exception $e) {
        }

        return $count;
    }

    /**
     * 更新素材信息
     * Author   Martinsun<syh@sunyonghong.com>
     * Date 2020-08-25
     *
     * @param string $field [description]
     * @param    [type]                         $value [description]
     * @param int    $id    [description]
     */
    public function updateMaterial(string $field, $value, int $id)
    {
        $material = $this->where('id', $id)->findOrFail();
        if ($field == 'duration') {
            // 计算时长
            $value = Tool::strToSecond($value);
        }
        $material->attach->$field = $value;
        if (!$material->attach->save()) {
            throw new LogicException('更新失败');
        }

        Log::write('更新素材【' . $material->attach->filename . '】', 'material', 'update', true);
    }

    /**
     * 获取未分组的素材数量
     * Author: Martinsun <syh@sunyonghong.com>
     * Date: 2021/5/18
     *
     * @param string $type
     * @return int
     */
    public function getUncategoryCount(string $type): int
    {
        return $this->scope('materialType', $type)->where('material_category_id', -1)->count('id');
    }
}
